#ifndef __R_DATASOURCE_S4_H__
#define __R_DATASOURCE_S4_H__


#include <Rcpp.h>
#include "WrapDefs.h"

namespace UGC
{
	class UGDataSource;
	class UGDatasetVector;
	class UGDataset;
	class UGDatasetRaster;
}


namespace RSuperMap{

#if defined(RCPP_VERSION) && RCPP_VERSION <= Rcpp_Version(0,10,6)
#define SetSexp setSEXP
#define AsSexp  asSexp
#else
#define SetSexp set__
#define AsSexp  get__
#endif

	using namespace Rcpp;
	using namespace UGC;
	using Rcpp::S4;
	using namespace RSuperMap;

	class S4_Datasource : public Rcpp::S4 {
	public: 
		S4_Datasource(const UGDataSource* pDatasource) : S4("Datasource") {
			slot("pointer") = Rcpp::XPtr<UGDataSource>(const_cast<UGDataSource*>(pDatasource), false);
		}

		S4_Datasource(const S4_Datasource& other) : S4() { SetSexp(other.AsSexp()); }

		S4_Datasource& operator=(const S4_Datasource& other) {
			SetSexp(other.AsSexp());
			return *this;
		}
	};

	class S4_Dataset : public Rcpp::S4 {
	public: 
		S4_Dataset(const UGDataset* pDT) : S4("Dataset") {
			slot("pointer") = Rcpp::XPtr<UGDataset>(const_cast<UGDataset*>(pDT), false);
		}

		S4_Dataset(const S4_Dataset& other) : S4() { SetSexp(other.AsSexp()); }

		S4_Dataset& operator=(const S4_Dataset& other) {
			SetSexp(other.AsSexp());
			return *this;
		}
	};
	
	class S4_DatasetVector : public Rcpp::S4 {
	public: 
		S4_DatasetVector(const UGDatasetVector* pDT) : S4("DatasetVector") {
			slot("pointer") = Rcpp::XPtr<UGDatasetVector>(const_cast<UGDatasetVector*>(pDT), false);
		}

		S4_DatasetVector(const S4_DatasetVector& other) : S4() { SetSexp(other.AsSexp()); }

		S4_DatasetVector& operator=(const S4_DatasetVector& other) {
			SetSexp(other.AsSexp());
			return *this;
		}
	};

	class S4_DatasetRaster : public Rcpp::S4 {
	public: 
		S4_DatasetRaster(const UGDatasetRaster* pDT) : S4("DatasetRaster") {
			slot("pointer") = Rcpp::XPtr<UGDatasetRaster>(const_cast<UGDatasetRaster*>(pDT), false);
		}

		S4_DatasetRaster(const S4_DatasetRaster& other) : S4() { SetSexp(other.AsSexp()); }

		S4_DatasetRaster& operator=(const S4_DatasetRaster& other) {
			SetSexp(other.AsSexp());
			return *this;
		}
	};

#undef SetSexp
#undef AsSexp
}
#endif